


import javax.annotation.PostConstruct;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class BusServer {

    public static int counts = 0;
    static int counts1 = 0;
    static int counts2 = 0;
    int port = 8088;
    /* 标识数字 */
    private int flag = 0;
    /* 缓冲区大�? */
    private int BLOCK = 2009600;
    /* 接受数据缓冲�? */
    /* 发�?�数据缓冲区 */
    private ByteBuffer receivebuffer = ByteBuffer.allocate(BLOCK);
    private Selector selector;
    private ServerSocketChannel server = null;
    private SocketChannel client = null;
    private Socket request = null;
    private boolean isReturn = true;
    List<String> lines = new ArrayList<>();
    private int cot = 0;
    int crc = 0;
    short[] s = new short[300];
    byte[] crccode;
    //定义返回的byte[]
    private short[] returnMeg = null;
    StringBuilder linkip = new StringBuilder();
    short[] datas = null;
    ;
    int linkprot = 0;
    ServerSocketChannel serverSocketChannel;
public static void main(String[] args) {
	BusServer b = new BusServer();
	b.init();
}
    public void connection(int port) throws IOException {
        serverSocketChannel = null;
        // 打开服务器套接字通道
        serverSocketChannel = ServerSocketChannel.open();

        // 服务器配置为非阻�?
        serverSocketChannel.configureBlocking(false);
        // �?索与此�?�道关联的服务器套接�?
        ServerSocket serverSocket = serverSocketChannel.socket();
        // 进行服务的绑�?
        serverSocket.bind(new InetSocketAddress(port));
        // 通过open()方法找到Selector
        selector = Selector.open();
        // 注册到selector，等待连�?
        serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
    }

    public void init() {
        Thread thread = new Thread(() -> {
            try {
                listen();
            } catch (IOException e) {
            	e.printStackTrace();
            }
        });
        thread.start();

    }

    // 监听
    public void listen() throws IOException {
        connection(port);
        boolean flag = true;
        for (; flag; ) {
            try {
                // 选择�?组键，并且相应的通道已经打开
                selector.select();
                // 返回此�?�择器的已�?�择键集�?
                Set<SelectionKey> selectionKeys = selector.selectedKeys();
                Iterator<SelectionKey> iterator = selectionKeys.iterator();
                while (iterator.hasNext()) {
                    SelectionKey selectionKey = iterator.next();
                    iterator.remove();
                    handleKey(selectionKey);
                }
            } catch (Exception e) {
                e.printStackTrace();
                flag = false;
                selector.close();
                newserver();
            }
        }
    }


    public static void add() {
        counts++;
    }


    // 处理请求
    private void handleKey(final SelectionKey selectionKey) throws IOException {
        // 接受请求
        String receiveText;
        try {

            int count = 0;
            // 测试此键的�?�道是否已准备好接受新的套接字连接�??
            if (selectionKey.isAcceptable()) {
                //Sy	stem.out.println(selectionKey.isAcceptable());
//				// 返回为之创建此键的�?�道�?
                server = (ServerSocketChannel) selectionKey.channel();
                // 接受到此通道套接字的连接�?
                // 此方法返回的套接字�?�道（如果有）将处于阻塞模式�?
                client = server.accept();
                // 配置为非阻塞
                //System.out.println("Accepted connection from:" + client.socket());

                client.configureBlocking(false);
                // 注册到selector，等待连�?
                client.register(selector, SelectionKey.OP_READ);
                //client.close();

            } else if (selectionKey.isReadable()) {
                //System.out.print ( jdbc.formateDate2()+"  原始数据:"+ (counts2++)   +"   ");
                // 返回为之创建此键的�?�道�?
                client = (SocketChannel) selectionKey.channel();

                // 将缓冲区清空以备下次读取
                receivebuffer.clear();
                // 读取服务器发送来的数据到缓冲区中
                try {
                    count = client.read(receivebuffer);
                } catch (Exception e) {
                	e.printStackTrace();
                }
                if (count > 0) {
                    //System.out.print(count+"     ");
                     byte[] bs = receivebuffer.array();
                    executeADD(bs, selectionKey);
                }
            }
//            else if (selectionKey.isWritable()) {
//                System.out.println("NONONO");
//            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void newserver() {
        try {
            serverSocketChannel.close();
            connection(port);
            listen();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

    public void executeADD(byte[] bs, SelectionKey selectionKey) {
        if (bs != null) {
           
            try {
            	this.resolve(bs, selectionKey);
            } catch (Exception e) {
                e.printStackTrace();
            }
            //算法的数据长度为转义后长�?
        }

    }


    private short[] getBoby(short[] data, int startindex, int endindex) {
        short[] sdata = new short[endindex - startindex];
        for (int i = startindex, j = 0; i < endindex; i++, j++) {
            sdata[j] = data[i];
        }
        return sdata;
    }



    public String formateDate2() {
        String nowtime = null;

        SimpleDateFormat ch = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss",
                Locale.CHINESE);

        nowtime = ch.format(new Date());
        return nowtime;
    }

    private void resolve(byte[] datas, SelectionKey selectionKey) throws IOException {
    	String s = new String(datas).trim();
    
    	DesUtils des = new DesUtils("a3VPjsfeF0YmmwVQ"); //自定义密钥
    	try {
			System.out.println(des.decrypt(s));
			 prinltWrite(selectionKey, client, s.getBytes());
		} catch (Exception e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
    	
///			System.out.print("业务:  "+msg_id);
        
//        switch (msg_id) {
//            case Define.UP_CONNECT_REQ:
//
//                try {
//                   
//                    prinltWrite(selectionKey, client, returnMegs);
//                    if (sendMsg == 0) {//发�?�从链路登陆
//                        //new Cliet1(linkip.toString().trim(), linkprot);
//                    }
//                    cot++;
//                    if (cot == 20) {
//                        //client.close();
//                    }
//                } catch (Exception e) {
//                    e.printStackTrace();
//                    smsAlarm.sendAlarm(e.getMessage());
//                }
//                break;
//            
//
//           
//            default:
//                break;
//        }
        try {
            client.register(selector, SelectionKey.OP_READ);
        } catch (Exception e) {
        	e.printStackTrace();
        }

    }


    private void prinltWrite(SelectionKey selectionKey, SocketChannel client, byte[] returnMeg) throws IOException {
        // 将缓冲区清空以备下次写入
    	ByteBuffer sendbuffer = ByteBuffer.allocate(BLOCK);
        
        sendbuffer.put(returnMeg);
        // 将缓冲区各标志复�?,因为向里面put了数据标志被改变要想从中读取数据发向服务�?,就要复位
        sendbuffer.flip();
        // 输出到道
        if (returnMeg != null) {
            client.write(sendbuffer);
            
        }
        returnMeg = null;

    }
}






